package com.mall.user.services;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.converter.UserConverterMapper;
import com.mall.user.converter.UserVerifyConverter;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dto.*;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * author : wangdezhao
 * date : 2021/6/17
 * description : 登录接口
 */
@Slf4j
@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserConverterMapper UserConverter;

    @Autowired
    UserVerifyConverter userVerifyConverter;


    @Override
    public UserLoginResponse loginPost(userLoginRequest request) {
        UserLoginResponse userLoginResponse = new UserLoginResponse();
        try {
            request.requestCheck(); // 先参数校验
            String username = request.getUserName(); // 根据username 去user_member表中查询
            String password = request.getPassword(); // 用户输入的密码
            String passwordMD5 = SecureUtil.md5(password); // md加密后 去和数据库中查询后的结果进行校验

            Member member = getMember(username);

            // 检查密码是否正确
            if (!member.getPassword().equals(passwordMD5)) { // 如果不对,直接抛出异常
                throw new Exception(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
            }

            userLoginResponse = UserConverter.converter(member); // 转换成response对象

            // 改成map 转 token
            Map<String, String> map = new LinkedHashMap<>();
            map.put("uid", String.valueOf(member.getId()));
            map.put("username", member.getUsername());
            String mapJson = JSONUtil.toJsonStr(map);
            String token = JwtTokenUtils.builder().msg(mapJson).build().creatJwtToken(); // 根据map对象生成token

            // 成功, response对象赋值
            userLoginResponse.setToken(token);
            userLoginResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
            userLoginResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());

        } catch (Exception e) { // 没查到, 返回账号密码错误
            userLoginResponse.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
            userLoginResponse.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
        }
        return userLoginResponse;
    }

    /**
     * 校验登录
     *
     * @param request
     * @return
     */
    @Override
    public UserVerifyResponse loginGet(userLoginRequest request) {
        UserVerifyResponse response = new UserVerifyResponse();

        try {
            request.requestCheck();
            String token = request.getUserName(); // 取出token
            String json = JwtTokenUtils.builder().token(token).build().freeJwt(); // token中取出username
            Map<String,String> map = JSONUtil.toBean(json, Map.class);

            String username = map.get("username"); // 获得token中member对象的username

            Member member = getMember(username);

            response = userVerifyConverter.VerifyConverter(member); // 转成response对象

            response.setCode(SysRetCodeConstants.SUCCESS.getCode());
            response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
            return response;
        } catch (Exception e) { // 验证登录失败
            response.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
        }
        return response;
    }


    @Override
    public void loginOut() {

    }

    @Override
    public CheckAuthResponse validToken(CheckAuthRequest checkAuthRequest) {
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();

        try {
            String token = checkAuthRequest.getToken();
            String map = JwtTokenUtils.builder().token(token).build().freeJwt();
            JSONObject object = JSONUtil.parseObj(map);
            String username = object.get("username").toString();

            if (getMember(username) != null){ // 数据库中有数据
                checkAuthResponse.setUserinfo(map);
                checkAuthResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
                checkAuthResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
            }else {
                checkAuthResponse.setCode(SysRetCodeConstants.USERVERIFY_INFOR_INVALID.getCode());
                checkAuthResponse.setMsg(SysRetCodeConstants.USERVERIFY_INFOR_INVALID.getMessage());
            }

        } catch (Exception e) {
            log.error("token验证异常", e);
            ExceptionProcessorUtils.wrapperHandlerException(checkAuthResponse, e);
        }
        return checkAuthResponse;
    }

    // 获得 member 对象
    private Member getMember(String username) {
        Example example = new Example(Member.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", username);
        List<Member> members = memberMapper.selectByExample(example);    // 查出member对象
        return members.get(0);

    }
}
